﻿using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using rhIRC.Classes;
using rhIRC.Model;
using System;

namespace rhIRC.ViewModel
{
    /// <summary>
    /// This class contains properties that a View can data bind to.
    /// <para>
    /// See http://www.galasoft.ch/mvvm
    /// </para>
    /// </summary>
    public class IrcViewModel : ViewModelBase
    {
        private readonly IDataService _dataService;

        #region Properties
        private User currentUser;
        public User CurrentUser
        {
            get { return currentUser; }
            set
            {
                currentUser = value;
                this.RaisePropertyChanged(() => this.CurrentUser);
            }
        }

        private Channel currentChannel;
        public Channel CurrentChannel
        {
            get { return currentChannel; }
            set
            {
                currentChannel = value;
                this.RaisePropertyChanged(() => this.CurrentChannel);
            }
        }

        private Server currentServer;
        public Server CurrentServer
        {
            get { return currentServer; }
            set
            {
                currentServer = value;
                this.RaisePropertyChanged(() => this.CurrentServer);
            }
        }

        private IrcModel currentIrcConnector;
        public IrcModel CurrentIrcConnector
        {
            get { return currentIrcConnector; }
            set
            {
                currentIrcConnector = value;
                this.RaisePropertyChanged(() => this.CurrentIrcConnector);
            }
        }

        private string serverOutput;
        public string ServerOutput
        {
            get { return serverOutput; }
            set
            {
                serverOutput = value;
                this.RaisePropertyChanged(() => this.ServerOutput);
            }
        }

        private string userInput;
        public string UserInput
        {
            get { return userInput; }
            set
            {
                userInput = value;
                this.RaisePropertyChanged(() => this.UserInput);
            }
        }

        private IRC ircConnector;
        public IRC IrcConnector
        {
            get { return ircConnector; }
            set
            {
                ircConnector = value;
                this.RaisePropertyChanged(() => this.IrcConnector);
            }
        } 
        #endregion

        public IrcViewModel(IDataService dataService)
        {
            _dataService = dataService;
            _dataService.CreateServer((item, error) =>
                {
                    if (error != null)
                    {
                        return;
                    }

                    this.CurrentServer = item;
                }, new Server("irc.rizon.net", 6660));

            System.Console.WriteLine("Server: " + CurrentServer.Adres + " " + CurrentServer.Port);

            _dataService.CreateUser((item, error) =>
            {
                if (error != null)
                {
                    return;
                }

                this.CurrentUser= item;
            }, new User("rhIRC"));

            System.Console.WriteLine("User: " + CurrentUser.Name);

            _dataService.CreateChannel((item, error) =>
            {
                if (error != null)
                {
                    return;
                }

                this.CurrentChannel = item;
            }, new Channel("#rhIRCTest"));

            System.Console.WriteLine("Channel: " + CurrentChannel.Adres);

            IrcConnector = new IRC(CurrentServer, CurrentUser, CurrentChannel);

            IrcConnector.eventServerMessage += IrcConnector_eventServerMessage;

            IrcConnector.Connect();

            AssignCommandToMethods();
        }

        #region Commands
        public RelayCommand SendUserInput { get; private set; }

        void AssignCommandToMethods()
        {
            SendUserInput = new RelayCommand(OnSendUserInput, () => true);
        }

        void OnSendUserInput()
        {
            if (UserInput[0].CompareTo('/') == 0)
            {
                UserInput = UserInput.Substring(1);
                this.IrcConnector.ReadUserInput(this.UserInput);
            }
            else
                this.IrcConnector.ReadUserInput(String.Format("PRIVMSG {0} :{1}", this.CurrentChannel.Adres, this.UserInput));

            this.UserInput = String.Empty;
        }
        #endregion

        #region Events
        void IrcConnector_eventServerMessage(string ServerMessage)
        {
            OutputLine(ServerMessage);
        }

        void IrcConnector_eventReceiving(string IrcCommand)
        {
            OutputLine(IrcCommand);
        } 
        #endregion

        #region Methods
        private void OutputLine(string line)
        {
            if (ServerOutput != null)
            {
                string tmp = ServerOutput;
                this.ServerOutput = line + Environment.NewLine + tmp;
            }
            else
                ServerOutput = line;
        } 
        #endregion
    }
}